﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace katOS
{
    class Parser
    {
        LinkedList<String> instructions = new LinkedList<string>();
        String[,] Symbols_table;

        public Parser(Process process, string filename)
        {
            RemoveComments();
            getInstructionSet(process, filename);
        }

        public LinkedList<String> getInstructionSet(Process process, string filename) 
        {
            filename = "C:/Users/kareAndy/Documents/UVG/Ciclo 5/CC3002 Sistemas Operativos/Proyecto No. 1/katOSFiles/" +process.getFileName()+ ".txt";
            StreamReader read_file;
            bool correct = true;
            string input;

            try
            {
                read_file = File.OpenText(filename);
                input = read_file.ReadLine();
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.Message);
                correct = false;
                input = null;
                read_file = null;
            }
            if (correct)
            {
                while (input != null)
                {
                    instructions.AddLast(input);
                    input = read_file.ReadLine();
                }
                read_file.Close();
                SymbolsTable(process, instructions);
                return instructions;
            }
            return null;
        }

        private void RemoveComments() 
        {
            for(int i=0;i<this.instructions.Count;i++)
            {
                if(instructions.ElementAt(i).StartsWith(";"))
                {
                    instructions.Remove(instructions.ElementAt(i));
                }
            }

            for(int i=0;i<this.instructions.Count;i++)
            {
                if(this.instructions.ElementAt(i).CompareTo("")==0)
                {
                    this.instructions.Remove(instructions.ElementAt(i--));
                }
            }
            Remove_Spaces();
        }

        private void Remove_Spaces()
        {
            for(int i=0;i<this.instructions.Count;i++)
            {                String temp = Remove_Spaces(instructions.ElementAt(i));
                instructions.Remove(instructions.ElementAt(i));
                instructions.AddLast(temp);
            }
        }
     
         private String Remove_Spaces(string instruction)
         {
             string no_spaces = instruction;
             while(no_spaces.Contains(" "))
             {
                no_spaces = no_spaces.Replace("   "," ");
             }
             if(no_spaces.StartsWith(" "))
             {
                no_spaces = no_spaces.Substring(1);
             }
             if(no_spaces.EndsWith(" "))
             {
                no_spaces = no_spaces.Substring(0,no_spaces.Length-1);
             }
             if(no_spaces.Length==0)
             {
                 return "";
             }
             return no_spaces;     
        }

        public LinkedList<String> getInstructionSet()
        {
            return instructions;
        }

        public void SymbolsTable(Process process, LinkedList<String> instructions)
        {
            LinkedList<String> tags = new LinkedList<String>();
            LinkedList<String> tag_line = new LinkedList<String>();
            Symbols_table = new String[tags.Count,2];


            for (int i = 0; i < this.instructions.Count; i++)
            {
                String temp = instructions.ElementAt(i);

                if (temp.StartsWith("\'") && temp.EndsWith("\'"))
                {
                    String a_tag = temp.Substring(1, temp.Length - 1);
                    if (a_tag.Contains(" ") == false)
                    {
                        tags.AddLast(a_tag);
                        tag_line.AddLast(i+"");
                        instructions.Remove(instructions.ElementAt(i--));
                    }
                    else
                    {
                        Console.WriteLine("Wrong tag definition at line " + tag_line.ElementAt(i));
                    }
                }
            }

            for (int i = 0; i < tags.Count; i++)
            {
                 Symbols_table[i,0] = (tags.ElementAt(i));
                 Symbols_table[i,1] = (tag_line.ElementAt(i));
            }
            process.setSymbolsTable(Symbols_table);
        }

        public String[,] getSymbolsTable()
        {
            return Symbols_table;
        }
    }
}
